package org.cybzacg.encryption.factory;

import org.cybzacg.encryption.core.Encryptor;
import org.cybzacg.encryption.impl.AESEncryptor;
import org.cybzacg.encryption.impl.RSAEncryptor;
import org.cybzacg.encryption.enums.EncryptionAlgorithm;
import org.cybzacg.encryption.model.RegistrationResult;
import org.cybzacg.encryption.model.RegistrationStatistics;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicLong;
import java.lang.reflect.Modifier;

/**
 * 自动加密器注册器
 * 自动发现和注册加密器实现
 * 
 * @author encryption team
 * @version 1.0
 */
public class AutoEncryptorRegistrar {
    
    private static volatile AutoEncryptorRegistrar instance;
    private static final Object LOCK = new Object();
    
    private final Map<EncryptionAlgorithm, List<Class<? extends Encryptor>>> algorithmMap;
    private final Map<String, Class<? extends Encryptor>> classNameMap;
    private final List<Encryptor> registeredInstances;
    private final AtomicLong totalRegistrations;
    private final AtomicLong successfulRegistrations;
    private final AtomicLong failedRegistrations;
    
    private volatile boolean initialized = false;
    
    /**
     * 私有构造函数
     */
    private AutoEncryptorRegistrar() {
        this.algorithmMap = new ConcurrentHashMap<>();
        this.classNameMap = new ConcurrentHashMap<>();
        this.registeredInstances = new CopyOnWriteArrayList<>();
        this.totalRegistrations = new AtomicLong(0);
        this.successfulRegistrations = new AtomicLong(0);
        this.failedRegistrations = new AtomicLong(0);
    }
    
    /**
     * 获取单例实例
     * 
     * @return 注册器实例
     */
    public static AutoEncryptorRegistrar getInstance() {
        if (instance == null) {
            synchronized (LOCK) {
                if (instance == null) {
                    instance = new AutoEncryptorRegistrar();
                }
            }
        }
        return instance;
    }
    
    /**
     * 初始化注册器
     */
    public void initialize() {
        if (initialized) {
            return;
        }
        
        synchronized (this) {
            if (initialized) {
                return;
            }
            
            try {
                // 注册内置加密器
                registerBuiltInEncryptors();
                
                // 扫描并注册其他加密器
                scanAndRegisterEncryptors();
                
                initialized = true;
                
            } catch (Exception e) {
                throw new RuntimeException("Failed to initialize AutoEncryptorRegistrar", e);
            }
        }
    }
    
    /**
     * 注册内置加密器
     */
    private void registerBuiltInEncryptors() {
        // 注册AES加密器
        registerEncryptor(AESEncryptor.class);
        
        // 注册RSA加密器
        registerEncryptor(RSAEncryptor.class);
    }
    
    /**
     * 扫描并注册加密器
     */
    private void scanAndRegisterEncryptors() {
        try {
            // 扫描org.cybzacg.encryption.impl包
            String packageName = "org.cybzacg.encryption.impl";
            scanPackage(packageName);
            
        } catch (Exception e) {
            // 扫描失败不应该阻止初始化
            System.err.println("Failed to scan for encryptors: " + e.getMessage());
        }
    }
    
    /**
     * 扫描指定包
     */
    private void scanPackage(String packageName) {
        try {
            // 这里应该使用类路径扫描，简化实现
            // 在实际项目中，可以使用Reflections或其他扫描库
            
            // 模拟扫描过程
            List<Class<?>> classes = getClassesInPackage(packageName);
            
            for (Class<?> clazz : classes) {
                if (Encryptor.class.isAssignableFrom(clazz) && 
                    !Modifier.isAbstract(clazz.getModifiers()) &&
                    !Modifier.isInterface(clazz.getModifiers())) {
                    
                    @SuppressWarnings("unchecked")
                    Class<? extends Encryptor> encryptorClass = 
                        (Class<? extends Encryptor>) clazz;
                    
                    registerEncryptor(encryptorClass);
                }
            }
            
        } catch (Exception e) {
            System.err.println("Failed to scan package " + packageName + ": " + e.getMessage());
        }
    }
    
    /**
     * 获取包中的类（简化实现）
     */
    private List<Class<?>> getClassesInPackage(String packageName) {
        // 简化实现，实际应该使用类路径扫描
        List<Class<?>> classes = new ArrayList<>();
        
        // 添加已知的加密器类
        classes.add(AESEncryptor.class);
        classes.add(RSAEncryptor.class);
        
        return classes;
    }
    
    /**
     * 注册加密器类
     * 
     * @param encryptorClass 加密器类
     * @return 注册结果
     */
    public RegistrationResult registerEncryptor(Class<? extends Encryptor> encryptorClass) {
        totalRegistrations.incrementAndGet();
        
        try {
            // 验证类
            if (!isValidEncryptorClass(encryptorClass)) {
                failedRegistrations.incrementAndGet();
                return RegistrationResult.failure(
                    encryptorClass.getName(), 
                    "Invalid encryptor class"
                );
            }
            
            // 创建实例以获取算法信息
            Encryptor instance = createInstance(encryptorClass);
            if (instance == null) {
                failedRegistrations.incrementAndGet();
                return RegistrationResult.failure(
                    encryptorClass.getName(), 
                    "Failed to create instance"
                );
            }
            
            // 获取支持的算法
            EncryptionAlgorithm algorithm = instance.getAlgorithm();
            if (algorithm == null) {
                failedRegistrations.incrementAndGet();
                return RegistrationResult.failure(
                    encryptorClass.getName(), 
                    "Algorithm not specified"
                );
            }
            
            // 注册到算法映射
            algorithmMap.computeIfAbsent(algorithm, k -> new ArrayList<>()).add(encryptorClass);
            
            // 注册到类名映射
            classNameMap.put(encryptorClass.getName(), encryptorClass);
            
            // 添加到实例列表
            registeredInstances.add(instance);
            
            successfulRegistrations.incrementAndGet();
            
            return RegistrationResult.success(
                encryptorClass.getName(), 
                "Successfully registered for algorithm: " + algorithm
            );
            
        } catch (Exception e) {
            failedRegistrations.incrementAndGet();
            return RegistrationResult.failure(
                encryptorClass.getName(), 
                "Registration failed: " + e.getMessage()
            );
        }
    }
    
    /**
     * 验证加密器类
     */
    private boolean isValidEncryptorClass(Class<? extends Encryptor> encryptorClass) {
        if (encryptorClass == null) {
            return false;
        }
        
        // 检查是否为抽象类或接口
        int modifiers = encryptorClass.getModifiers();
        if (Modifier.isAbstract(modifiers) || Modifier.isInterface(modifiers)) {
            return false;
        }
        
        // 检查是否有无参构造函数
        try {
            encryptorClass.getDeclaredConstructor();
        } catch (NoSuchMethodException e) {
            return false;
        }
        
        return true;
    }
    
    /**
     * 创建加密器实例
     */
    private Encryptor createInstance(Class<? extends Encryptor> encryptorClass) {
        try {
            return encryptorClass.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            return null;
        }
    }
    
    /**
     * 获取指定算法的加密器类列表
     * 
     * @param algorithm 加密算法
     * @return 加密器类列表
     */
    public List<Class<? extends Encryptor>> getEncryptorClasses(EncryptionAlgorithm algorithm) {
        initialize();
        return algorithmMap.getOrDefault(algorithm, new ArrayList<>());
    }
    
    /**
     * 获取所有注册的加密器类
     * 
     * @return 加密器类映射
     */
    public Map<EncryptionAlgorithm, List<Class<? extends Encryptor>>> getAllEncryptorClasses() {
        initialize();
        return new HashMap<>(algorithmMap);
    }
    
    /**
     * 根据类名获取加密器类
     * 
     * @param className 类名
     * @return 加密器类，如果未找到返回null
     */
    public Class<? extends Encryptor> getEncryptorClass(String className) {
        initialize();
        return classNameMap.get(className);
    }
    
    /**
     * 获取所有注册的实例
     * 
     * @return 加密器实例列表
     */
    public List<Encryptor> getRegisteredInstances() {
        initialize();
        return new ArrayList<>(registeredInstances);
    }
    
    /**
     * 获取指定算法的实例
     * 
     * @param algorithm 加密算法
     * @return 加密器实例列表
     */
    public List<Encryptor> getInstances(EncryptionAlgorithm algorithm) {
        initialize();
        List<Encryptor> instances = new ArrayList<>();
        
        for (Encryptor instance : registeredInstances) {
            if (instance.getAlgorithm() == algorithm) {
                instances.add(instance);
            }
        }
        
        return instances;
    }
    
    /**
     * 检查算法是否已注册
     * 
     * @param algorithm 加密算法
     * @return 是否已注册
     */
    public boolean isAlgorithmRegistered(EncryptionAlgorithm algorithm) {
        initialize();
        return algorithmMap.containsKey(algorithm) && !algorithmMap.get(algorithm).isEmpty();
    }
    
    /**
     * 获取注册统计信息
     * 
     * @return 统计信息
     */
    public RegistrationStatistics getStatistics() {
        initialize();
        
        Map<EncryptionAlgorithm, Integer> algorithmCounts = new HashMap<>();
        for (Map.Entry<EncryptionAlgorithm, List<Class<? extends Encryptor>>> entry : algorithmMap.entrySet()) {
            algorithmCounts.put(entry.getKey(), entry.getValue().size());
        }
        
        return new RegistrationStatistics(
            totalRegistrations.get(),
            successfulRegistrations.get(),
            failedRegistrations.get(),
            algorithmCounts,
            new ArrayList<>(classNameMap.keySet())
        );
    }
    
    /**
     * 清除所有注册
     */
    public void clearRegistrations() {
        synchronized (this) {
            algorithmMap.clear();
            classNameMap.clear();
            registeredInstances.clear();
            totalRegistrations.set(0);
            successfulRegistrations.set(0);
            failedRegistrations.set(0);
            initialized = false;
        }
    }
    
    /**
     * 重新初始化
     */
    public void reinitialize() {
        clearRegistrations();
        initialize();
    }
    
    /**
     * 获取支持的算法列表
     * 
     * @return 支持的算法列表
     */
    public List<EncryptionAlgorithm> getSupportedAlgorithms() {
        initialize();
        return new ArrayList<>(algorithmMap.keySet());
    }
    
    /**
     * 检查是否已初始化
     * 
     * @return 是否已初始化
     */
    public boolean isInitialized() {
        return initialized;
    }
    
    /**
     * 获取注册器信息
     * 
     * @return 注册器信息字符串
     */
    public String getRegistrarInfo() {
        if (!initialized) {
            return "AutoEncryptorRegistrar not initialized";
        }
        
        StringBuilder sb = new StringBuilder();
        sb.append("AutoEncryptorRegistrar Status:\n");
        sb.append("  Initialized: ").append(initialized).append("\n");
        sb.append("  Total Registrations: ").append(totalRegistrations.get()).append("\n");
        sb.append("  Successful: ").append(successfulRegistrations.get()).append("\n");
        sb.append("  Failed: ").append(failedRegistrations.get()).append("\n");
        sb.append("  Supported Algorithms: ").append(algorithmMap.size()).append("\n");
        
        for (Map.Entry<EncryptionAlgorithm, List<Class<? extends Encryptor>>> entry : algorithmMap.entrySet()) {
            sb.append("    ").append(entry.getKey()).append(": ").append(entry.getValue().size()).append(" classes\n");
        }
        
        return sb.toString();
    }
}
